Introduction

Today’s recitation materials are on a bunch of stuff I thought was interesting but didn’t fit specifically into any of the other lessons. This includes some cool ggplot extension packages we haven’t gone over yet, and heatmaps that utilize base R plotting.

Load libraries

Loading the libraries that are for each section. Individual libraries are before each section so you can see which go with what plot types.

library(tidyverse) # for everything
library(gghighlight) # for highlighting
library(gganimate) # animating plots
library(ggrepel) # for text/label repelling
library(magick) # for gif rendering
library(scales) # for easy scaling
library(plotly) # for ggplotly
library(glue) # for easy pasting

library(gapminder) # for data for viz2

Really start using an Rproject 📽️

A cartoon of a cracked glass cube looking frustrated with casts on its arm and leg, with bandaids on it, containing “setwd”, looks on at a metal riveted cube labeled “R Proj” holding a skateboard looking sympathetic, and a smaller cube with a helmet on labeled “here” doing a trick on a skateboard.

Artwork by @allison_horst

If you don’t have a Rproject for class, set one up.

Visualization 1

We are going to interrogate a dataset from Gapminder that includes information about Happiness Scores collected across different countries and years.

Create a visualization that shows the happiness scores for all countries from 2008 to 2010. Highlight in some way the top 3 countries with the highest happiness scores per continent.

I’ve put the data on Github so you can easily download it with the code below. Note, the question asks you to make a plot considering continent so I’ve also provided you a key that has each country, and the continent to which it belows for you to join together.

happiness <- read_csv("data/hapiscore_whr.csv")
country_continent <- read_csv("data/country_continent.csv")

Wrangle

# join happinesn and country_continent 
# so we can see which continent goes which each country 
happiness_country <- left_join(happiness, country_continent, by = "country")

# make tidy data and convert year from character to numeric
happiness_tidy <- happiness_country %>%
  pivot_longer(cols = -c(country, continent),
               names_to = "year",
               values_to = "rating") %>%
  mutate(year = as.numeric(year))

# create a df that has the maximum happiness rating across the time 
# period per country by continent
max_happiness <- happiness_tidy %>%
  filter(year %in% c(2008:2020)) %>%
  drop_na(rating) %>%
  group_by(continent, country) %>%
  summarize(max_rating = max(rating)) 

# pull the top 3 happiness countries for each continent
top3_happiest <- max_happiness %>%
  ungroup() %>%
  group_by(continent) %>%
  slice_max(max_rating, n = 3) %>%
  ungroup()

Plot

happiness_tidy %>%
  filter(year %in% c(2008:2020)) %>%
  ggplot(aes(x = year, y = rating, group = country, color = continent)) +
  geom_line() +
  scale_x_continuous(breaks = seq(2004, 2020, 4)) +
  gghighlight(country %in% top3_happiest$country,
              label_params = list(size = 3)) +
  facet_wrap(vars(continent)) +
  theme_classic() +
  theme(legend.position = "none",
        axis.text.x = element_text(angle = 45, margin=margin(t=8))) +
  labs(x = "Year",
       y = "Happiness Rating (out of 100)",
       title = "Happiness ratings for each country by continent over 2008 to 2020",
       subtitle = "Data from Gapminder.org")

Visualization 2

Recreate a plot in the vein of the one here. You can make the same interactive plot (use the data from 2007, which is slightly older and different from what you see in the online plot), or choose to animate it over year. Or do both.

Use the data gapminder::gapminder which you can access from R.

Interactive

glimpse(gapminder)
## Rows: 1,704
## Columns: 6
## $ country   <fct> "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan", …
## $ continent <fct> Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, …
## $ year      <int> 1952, 1957, 1962, 1967, 1972, 1977, 1982, 1987, 1992, 1997, …
## $ lifeExp   <dbl> 28.801, 30.332, 31.997, 34.020, 36.088, 38.438, 39.854, 40.8…
## $ pop       <int> 8425333, 9240934, 10267083, 11537966, 13079460, 14880372, 12…
## $ gdpPercap <dbl> 779.4453, 820.8530, 853.1007, 836.1971, 739.9811, 786.1134, …
income_by_lifeexp <- gapminder %>%
  filter(year == 2007) %>%
  ggplot(aes(gdpPercap, y = lifeExp, fill = continent, size = pop,
             text = glue("Country: {country}
                         Continent: {continent}
                         GDP per capita: ${round(gdpPercap, 0)}
                         Life expectancy: {round(lifeExp, 0)}"))) +
  geom_point(shape = 21, color = "black") +
  scale_x_continuous(trans = "log2", labels=scales::dollar_format()) +
  scale_size_area(guide = "none") +
  coord_cartesian(ylim = c(0, 90)) +
  theme_minimal() +
  theme(legend.position = "top") +
  labs(x = "GDP per capita",
       y = "Life expectancy",
       fill = "Continent",
       title = "Relationship between GDP per capita and life expectancy 
from 1952 to 2007",
       caption = "Data from Gapminder.org")

ggplotly(income_by_lifeexp, tooltip = "text")

Animated

income_by_lifeexp_anim <- gapminder %>%
  ggplot(aes(gdpPercap, y = lifeExp, fill = continent, size = pop,
             text = glue("Country: {country}
                         Continent: {continent}
                         GDP per capita: ${round(gdpPercap, 0)}
                         Life expectancy: {round(lifeExp, 0)}"))) +
  geom_point(shape = 21, color = "black") +
  scale_x_continuous(trans = "log2", labels=scales::dollar_format()) +
  scale_size_area(guide = "none") +
  coord_cartesian(ylim = c(0, 90)) +
  theme_minimal() +
  theme(legend.position = "top") +
  labs(x = "GDP per capita",
       y = "Life expectancy",
       fill = "Continent",
       title = "Relationship between GDP per capita and life expectancy 
from 1952 to 2007",
       subtitle = "Year = {closest_state}",
       caption = "Data from Gapminder.org") +
  transition_states(year)

# set parameters for your animation
(animated_plot <- animate(plot = income_by_lifeexp_anim, 
                        duration = 10, 
                        fps = 10, 
                        width = 700, 
                        height = 400,
                        renderer = magick_renderer()))

LS0tCnRpdGxlOiAiTGVmdG92ZXIgdGlkYml0cyByZWNpdGF0aW9uIHNvbHV0aW9ucyIKYXV0aG9yOiAiSmVzc2ljYSBDb29wZXJzdG9uZSIKZGF0ZTogIjExLzE1LzIwMjIiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdGhlbWU6IGZsYXRseQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFKQpgYGAKCiMjIEludHJvZHVjdGlvbgoKVG9kYXkncyByZWNpdGF0aW9uIG1hdGVyaWFscyBhcmUgb24gYSBidW5jaCBvZiBzdHVmZiBJIHRob3VnaHQgd2FzIGludGVyZXN0aW5nIGJ1dCBkaWRuJ3QgZml0IHNwZWNpZmljYWxseSBpbnRvIGFueSBvZiB0aGUgb3RoZXIgbGVzc29ucy4gVGhpcyBpbmNsdWRlcyBzb21lIGNvb2wgZ2dwbG90IGV4dGVuc2lvbiBwYWNrYWdlcyB3ZSBoYXZlbid0IGdvbmUgb3ZlciB5ZXQsIGFuZCBoZWF0bWFwcyB0aGF0IHV0aWxpemUgYmFzZSBSIHBsb3R0aW5nLgoKIyMjIExvYWQgbGlicmFyaWVzCkxvYWRpbmcgdGhlIGxpYnJhcmllcyB0aGF0IGFyZSBmb3IgZWFjaCBzZWN0aW9uLiBJbmRpdmlkdWFsIGxpYnJhcmllcyBhcmUgYmVmb3JlIGVhY2ggc2VjdGlvbiBzbyB5b3UgY2FuIHNlZSB3aGljaCBnbyB3aXRoIHdoYXQgcGxvdCB0eXBlcy4KYGBge3IgbG9hZCBsaWJyYXJpZXMsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIyBmb3IgZXZlcnl0aGluZwpsaWJyYXJ5KGdnaGlnaGxpZ2h0KSAjIGZvciBoaWdobGlnaHRpbmcKbGlicmFyeShnZ2FuaW1hdGUpICMgYW5pbWF0aW5nIHBsb3RzCmxpYnJhcnkoZ2dyZXBlbCkgIyBmb3IgdGV4dC9sYWJlbCByZXBlbGxpbmcKbGlicmFyeShtYWdpY2spICMgZm9yIGdpZiByZW5kZXJpbmcKbGlicmFyeShzY2FsZXMpICMgZm9yIGVhc3kgc2NhbGluZwpsaWJyYXJ5KHBsb3RseSkgIyBmb3IgZ2dwbG90bHkKbGlicmFyeShnbHVlKSAjIGZvciBlYXN5IHBhc3RpbmcKCmxpYnJhcnkoZ2FwbWluZGVyKSAjIGZvciBkYXRhIGZvciB2aXoyCmBgYAoKCiMjIFJlYWxseSBzdGFydCB1c2luZyBhbiBScHJvamVjdCDwn5O977iPCgpgYGB7ciBycHJvaiBpbGx1c3RyYXRpb24sIGZpZy5hbHQgPSAiQSBjYXJ0b29uIG9mIGEgY3JhY2tlZCBnbGFzcyBjdWJlIGxvb2tpbmcgZnJ1c3RyYXRlZCB3aXRoIGNhc3RzIG9uIGl0cyBhcm0gYW5kIGxlZywgd2l0aCBiYW5kYWlkcyBvbiBpdCwgY29udGFpbmluZyDigJxzZXR3ZOKAnSwgbG9va3Mgb24gYXQgYSBtZXRhbCByaXZldGVkIGN1YmUgbGFiZWxlZCDigJxSIFByb2rigJ0gaG9sZGluZyBhIHNrYXRlYm9hcmQgbG9va2luZyBzeW1wYXRoZXRpYywgYW5kIGEgc21hbGxlciBjdWJlIHdpdGggYSBoZWxtZXQgb24gbGFiZWxlZCDigJxoZXJl4oCdIGRvaW5nIGEgdHJpY2sgb24gYSBza2F0ZWJvYXJkLiIsIGZpZy5jYXA9ICJBcnR3b3JrIGJ5IFtAYWxsaXNvbl9ob3JzdF0oaHR0cHM6Ly90d2l0dGVyLmNvbS9hbGxpc29uX2hvcnN0KSIsIG91dC53aWR0aCA9ICI3MCUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIiwgZWNobyA9IEZBTFNFfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiaW1nL3Jwcm9qLnBuZyIpCmBgYAoKSWYgeW91IGRvbid0IGhhdmUgYSBScHJvamVjdCBmb3IgY2xhc3MsIHNldCBvbmUgdXAuCgojIyBWaXN1YWxpemF0aW9uIDEKV2UgYXJlIGdvaW5nIHRvIGludGVycm9nYXRlIGEgIGRhdGFzZXQgZnJvbSBbR2FwbWluZGVyXShodHRwczovL3d3dy5nYXBtaW5kZXIub3JnLykgdGhhdCBpbmNsdWRlcyBpbmZvcm1hdGlvbiBhYm91dCBbSGFwcGluZXNzIFNjb3Jlc10oaHR0cDovL2dhcG0uaW8vZGhhcGlzY29yZV93aHIpIGNvbGxlY3RlZCBhY3Jvc3MgZGlmZmVyZW50IGNvdW50cmllcyBhbmQgeWVhcnMuIAoKQ3JlYXRlIGEgdmlzdWFsaXphdGlvbiB0aGF0IHNob3dzIHRoZSBoYXBwaW5lc3Mgc2NvcmVzIGZvciBhbGwgY291bnRyaWVzIGZyb20gMjAwOCB0byAyMDEwLiBIaWdobGlnaHQgaW4gc29tZSB3YXkgdGhlIHRvcCAzIGNvdW50cmllcyB3aXRoIHRoZSBoaWdoZXN0IGhhcHBpbmVzcyBzY29yZXMgcGVyIGNvbnRpbmVudC4KCkkndmUgcHV0IHRoZSBkYXRhIG9uIEdpdGh1YiBzbyB5b3UgY2FuIGVhc2lseSBkb3dubG9hZCBpdCB3aXRoIHRoZSBjb2RlIGJlbG93LiBOb3RlLCB0aGUgcXVlc3Rpb24gYXNrcyB5b3UgdG8gbWFrZSBhIHBsb3QgY29uc2lkZXJpbmcgY29udGluZW50IHNvIEkndmUgYWxzbyBwcm92aWRlZCB5b3UgYSBrZXkgdGhhdCBoYXMgZWFjaCBjb3VudHJ5LCBhbmQgdGhlIGNvbnRpbmVudCB0byB3aGljaCBpdCBiZWxvd3MgZm9yIHlvdSB0byBqb2luIHRvZ2V0aGVyLgoKYGBge3Igdml6MSBkYXRhfQpoYXBwaW5lc3MgPC0gcmVhZF9jc3YoImRhdGEvaGFwaXNjb3JlX3doci5jc3YiKQpjb3VudHJ5X2NvbnRpbmVudCA8LSByZWFkX2NzdigiZGF0YS9jb3VudHJ5X2NvbnRpbmVudC5jc3YiKQpgYGAKCldyYW5nbGUKYGBge3Igdml6MSB3cmFuZ2xlfQojIGpvaW4gaGFwcGluZXNuIGFuZCBjb3VudHJ5X2NvbnRpbmVudCAKIyBzbyB3ZSBjYW4gc2VlIHdoaWNoIGNvbnRpbmVudCBnb2VzIHdoaWNoIGVhY2ggY291bnRyeSAKaGFwcGluZXNzX2NvdW50cnkgPC0gbGVmdF9qb2luKGhhcHBpbmVzcywgY291bnRyeV9jb250aW5lbnQsIGJ5ID0gImNvdW50cnkiKQoKIyBtYWtlIHRpZHkgZGF0YSBhbmQgY29udmVydCB5ZWFyIGZyb20gY2hhcmFjdGVyIHRvIG51bWVyaWMKaGFwcGluZXNzX3RpZHkgPC0gaGFwcGluZXNzX2NvdW50cnkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtYyhjb3VudHJ5LCBjb250aW5lbnQpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJ5ZWFyIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInJhdGluZyIpICU+JQogIG11dGF0ZSh5ZWFyID0gYXMubnVtZXJpYyh5ZWFyKSkKCiMgY3JlYXRlIGEgZGYgdGhhdCBoYXMgdGhlIG1heGltdW0gaGFwcGluZXNzIHJhdGluZyBhY3Jvc3MgdGhlIHRpbWUgCiMgcGVyaW9kIHBlciBjb3VudHJ5IGJ5IGNvbnRpbmVudAptYXhfaGFwcGluZXNzIDwtIGhhcHBpbmVzc190aWR5ICU+JQogIGZpbHRlcih5ZWFyICVpbiUgYygyMDA4OjIwMjApKSAlPiUKICBkcm9wX25hKHJhdGluZykgJT4lCiAgZ3JvdXBfYnkoY29udGluZW50LCBjb3VudHJ5KSAlPiUKICBzdW1tYXJpemUobWF4X3JhdGluZyA9IG1heChyYXRpbmcpKSAKCiMgcHVsbCB0aGUgdG9wIDMgaGFwcGluZXNzIGNvdW50cmllcyBmb3IgZWFjaCBjb250aW5lbnQKdG9wM19oYXBwaWVzdCA8LSBtYXhfaGFwcGluZXNzICU+JQogIHVuZ3JvdXAoKSAlPiUKICBncm91cF9ieShjb250aW5lbnQpICU+JQogIHNsaWNlX21heChtYXhfcmF0aW5nLCBuID0gMykgJT4lCiAgdW5ncm91cCgpCmBgYAoKUGxvdApgYGB7ciB2aXoxIHBsb3R9CmhhcHBpbmVzc190aWR5ICU+JQogIGZpbHRlcih5ZWFyICVpbiUgYygyMDA4OjIwMjApKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcmF0aW5nLCBncm91cCA9IGNvdW50cnksIGNvbG9yID0gY29udGluZW50KSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDIwMDQsIDIwMjAsIDQpKSArCiAgZ2doaWdobGlnaHQoY291bnRyeSAlaW4lIHRvcDNfaGFwcGllc3QkY291bnRyeSwKICAgICAgICAgICAgICBsYWJlbF9wYXJhbXMgPSBsaXN0KHNpemUgPSAzKSkgKwogIGZhY2V0X3dyYXAodmFycyhjb250aW5lbnQpKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgbWFyZ2luPW1hcmdpbih0PTgpKSkgKwogIGxhYnMoeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiSGFwcGluZXNzIFJhdGluZyAob3V0IG9mIDEwMCkiLAogICAgICAgdGl0bGUgPSAiSGFwcGluZXNzIHJhdGluZ3MgZm9yIGVhY2ggY291bnRyeSBieSBjb250aW5lbnQgb3ZlciAyMDA4IHRvIDIwMjAiLAogICAgICAgc3VidGl0bGUgPSAiRGF0YSBmcm9tIEdhcG1pbmRlci5vcmciKQpgYGAKCiMjIFZpc3VhbGl6YXRpb24gMgpSZWNyZWF0ZSBhIHBsb3QgaW4gdGhlIHZlaW4gb2YgdGhlIG9uZSBbaGVyZV0oaHR0cHM6Ly93d3cuZ2FwbWluZGVyLm9yZy90b29scy8jJGNoYXJ0LXR5cGU9YnViYmxlcyZ1cmw9djEpLiBZb3UgY2FuIG1ha2UgdGhlIHNhbWUgaW50ZXJhY3RpdmUgcGxvdCAodXNlIHRoZSBkYXRhIGZyb20gMjAwNywgd2hpY2ggaXMgc2xpZ2h0bHkgb2xkZXIgYW5kIGRpZmZlcmVudCBmcm9tIHdoYXQgeW91IHNlZSBpbiB0aGUgb25saW5lIHBsb3QpLCBvciBjaG9vc2UgdG8gYW5pbWF0ZSBpdCBvdmVyIGB5ZWFyYC4gT3IgZG8gYm90aC4KClVzZSB0aGUgZGF0YSBgZ2FwbWluZGVyOjpnYXBtaW5kZXJgIHdoaWNoIHlvdSBjYW4gYWNjZXNzIGZyb20gUi4KCiMjIyBJbnRlcmFjdGl2ZQpgYGB7ciB2aXoyIGludGVyYWN0aXZlfQpnbGltcHNlKGdhcG1pbmRlcikKCmluY29tZV9ieV9saWZlZXhwIDwtIGdhcG1pbmRlciAlPiUKICBmaWx0ZXIoeWVhciA9PSAyMDA3KSAlPiUKICBnZ3Bsb3QoYWVzKGdkcFBlcmNhcCwgeSA9IGxpZmVFeHAsIGZpbGwgPSBjb250aW5lbnQsIHNpemUgPSBwb3AsCiAgICAgICAgICAgICB0ZXh0ID0gZ2x1ZSgiQ291bnRyeToge2NvdW50cnl9CiAgICAgICAgICAgICAgICAgICAgICAgICBDb250aW5lbnQ6IHtjb250aW5lbnR9CiAgICAgICAgICAgICAgICAgICAgICAgICBHRFAgcGVyIGNhcGl0YTogJHtyb3VuZChnZHBQZXJjYXAsIDApfQogICAgICAgICAgICAgICAgICAgICAgICAgTGlmZSBleHBlY3RhbmN5OiB7cm91bmQobGlmZUV4cCwgMCl9IikpKSArCiAgZ2VvbV9wb2ludChzaGFwZSA9IDIxLCBjb2xvciA9ICJibGFjayIpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMiIsIGxhYmVscz1zY2FsZXM6OmRvbGxhcl9mb3JtYXQoKSkgKwogIHNjYWxlX3NpemVfYXJlYShndWlkZSA9ICJub25lIikgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLCA5MCkpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArCiAgbGFicyh4ID0gIkdEUCBwZXIgY2FwaXRhIiwKICAgICAgIHkgPSAiTGlmZSBleHBlY3RhbmN5IiwKICAgICAgIGZpbGwgPSAiQ29udGluZW50IiwKICAgICAgIHRpdGxlID0gIlJlbGF0aW9uc2hpcCBiZXR3ZWVuIEdEUCBwZXIgY2FwaXRhIGFuZCBsaWZlIGV4cGVjdGFuY3kgCmZyb20gMTk1MiB0byAyMDA3IiwKICAgICAgIGNhcHRpb24gPSAiRGF0YSBmcm9tIEdhcG1pbmRlci5vcmciKQoKZ2dwbG90bHkoaW5jb21lX2J5X2xpZmVleHAsIHRvb2x0aXAgPSAidGV4dCIpCmBgYAoKIyMjIEFuaW1hdGVkCmBgYHtyIHZpejIgYW5pbWF0ZWR9CmluY29tZV9ieV9saWZlZXhwX2FuaW0gPC0gZ2FwbWluZGVyICU+JQogIGdncGxvdChhZXMoZ2RwUGVyY2FwLCB5ID0gbGlmZUV4cCwgZmlsbCA9IGNvbnRpbmVudCwgc2l6ZSA9IHBvcCwKICAgICAgICAgICAgIHRleHQgPSBnbHVlKCJDb3VudHJ5OiB7Y291bnRyeX0KICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRpbmVudDoge2NvbnRpbmVudH0KICAgICAgICAgICAgICAgICAgICAgICAgIEdEUCBwZXIgY2FwaXRhOiAke3JvdW5kKGdkcFBlcmNhcCwgMCl9CiAgICAgICAgICAgICAgICAgICAgICAgICBMaWZlIGV4cGVjdGFuY3k6IHtyb3VuZChsaWZlRXhwLCAwKX0iKSkpICsKICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIGNvbG9yID0gImJsYWNrIikgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2cyIiwgbGFiZWxzPXNjYWxlczo6ZG9sbGFyX2Zvcm1hdCgpKSArCiAgc2NhbGVfc2l6ZV9hcmVhKGd1aWRlID0gIm5vbmUiKSArCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAsIDkwKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsKICBsYWJzKHggPSAiR0RQIHBlciBjYXBpdGEiLAogICAgICAgeSA9ICJMaWZlIGV4cGVjdGFuY3kiLAogICAgICAgZmlsbCA9ICJDb250aW5lbnQiLAogICAgICAgdGl0bGUgPSAiUmVsYXRpb25zaGlwIGJldHdlZW4gR0RQIHBlciBjYXBpdGEgYW5kIGxpZmUgZXhwZWN0YW5jeSAKZnJvbSAxOTUyIHRvIDIwMDciLAogICAgICAgc3VidGl0bGUgPSAiWWVhciA9IHtjbG9zZXN0X3N0YXRlfSIsCiAgICAgICBjYXB0aW9uID0gIkRhdGEgZnJvbSBHYXBtaW5kZXIub3JnIikgKwogIHRyYW5zaXRpb25fc3RhdGVzKHllYXIpCgojIHNldCBwYXJhbWV0ZXJzIGZvciB5b3VyIGFuaW1hdGlvbgooYW5pbWF0ZWRfcGxvdCA8LSBhbmltYXRlKHBsb3QgPSBpbmNvbWVfYnlfbGlmZWV4cF9hbmltLCAKICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSAxMCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGZwcyA9IDEwLCAKICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSA3MDAsIAogICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQgPSA0MDAsCiAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlcmVyID0gbWFnaWNrX3JlbmRlcmVyKCkpKQpgYGAKCgo=